//
//  NetworkReachabilityMonitor.m
//  EverBoxApp
//
//  Created by fanglin liu on 12-3-8.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "NetworkReachabilityMonitor.h"

static NetworkReachabilityMonitor* networkReachabilityMonitorInstance_;

void MySCNetworkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info);

@interface NetworkReachabilityMonitor()

- (void) notifyAllObserversReachability:(BOOL)bReachability;
- (void) createSCNetworkReachabilityRef;

@end

@implementation NetworkReachabilityMonitor

@synthesize monitoringModes = monitoringModes_;
@synthesize checkReachabilityHostname = checkReachabilityHostname_;


+ (NetworkReachabilityMonitor*) sharedNetworkReReachabilityMonitor
{
    if (nil == networkReachabilityMonitorInstance_) 
    {
        networkReachabilityMonitorInstance_ = [[NetworkReachabilityMonitor alloc] init];
    }

    return networkReachabilityMonitorInstance_;
}

- (id) init
{
    self = [super init];
    if (self) 
    {
        observers_ = [[NSMutableArray alloc] init];
        
    }
    
    return self;
}

- (void) dealloc
{
    CFRelease(networkReachabilityRef_);
    
    [observers_ release];
    
    [super dealloc];
}

- (void) createSCNetworkReachabilityRef
{
    networkReachabilityRef_ = SCNetworkReachabilityCreateWithName (NULL, [checkReachabilityHostname_ UTF8String]);
    SCNetworkReachabilityContext context;
    context.version = 0;
    context.info = self;
    context.retain = NULL;
    context.release = NULL;
    context.copyDescription = NULL;
    SCNetworkReachabilitySetCallback(networkReachabilityRef_, MySCNetworkReachabilityCallBack, &context);
}

- (void) setCheckReachabilityHostname:(NSString *)checkReachabilityHostname
{
    [checkReachabilityHostname retain];
    [checkReachabilityHostname_ release];
    checkReachabilityHostname_ = checkReachabilityHostname;
    
    [self createSCNetworkReachabilityRef];
}

- (void) startMonitor
{
    
    for (NSString* mode in self.monitoringModes) 
    {
        SCNetworkReachabilityScheduleWithRunLoop(networkReachabilityRef_, CFRunLoopGetCurrent(), (CFStringRef)mode);
    }

}

- (void) stopMonitor
{
    for (NSString* mode in self.monitoringModes) 
    {
        SCNetworkReachabilityScheduleWithRunLoop(networkReachabilityRef_, CFRunLoopGetCurrent(), (CFStringRef)mode);
    }
    
}

- (void) addObserver:(id<NetworkReachabilityMonitorProtocol>) anObserver
{
    [observers_ addObject:anObserver];
}


- (void) removeObserver:(id<NetworkReachabilityMonitorProtocol>) anObserver
{
    [observers_ removeObject:anObserver];    
}

- (void) notifyAllObserversReachability:(BOOL)bReachability
{
    for (id<NetworkReachabilityMonitorProtocol> anObserver in observers_) 
    {
        [anObserver onNetworkChangeReachability:bReachability];
    }
}


@end


void MySCNetworkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info)
{
    NetworkReachabilityMonitor* monitor = (NetworkReachabilityMonitor*)info;
    BOOL bReachability = ! (kSCNetworkFlagsConnectionRequired & flags);
    [monitor notifyAllObserversReachability:bReachability];
}
